<?php
require_once dirname(__FILE__).'/SimpleRecord_Revision.class.php';

define('SimpleRecord_AutoUnlock', 60 * 30);

class SimpleRecord {
	var $dir;
	var $count;
	var $revisions;

	function SimpleRecord($dbDir) {
		if(substr($dbDir, -1) != '/')
			$dbDir .= '/';

		if(!is_dir($dbDir)) {
			@mkdir($dbDir);
			@chmod($dbDir, 0777);
		}

		$this->dir = dir($dbDir);
		$this->count = null;
	}

	function getLength() {
		if(!is_null($this->count))
			return $this->count;
		else
			$this->count = 0;

		while($entry = $this->dir->read()) {
			if($entry === false)
				break;

			if($entry == '.' or substr($entry, 0, 2) != '0x')
				continue;

			++$this->count;
		}

		$this->dir->rewind();
		return $this->count;
	}

	function getChangeTimes($format = null) {
		$list = array();

		while($entry = $this->dir->read()) {
			if($entry === false)
				break;

			if(substr($entry, 0, 2) != '0x')
				continue;

			$list[hexdec(substr($entry, 2))] = filectime($this->dir->path.$entry);
		}

		$this->dir->rewind();

		for($i = 0; $format != null and $i < count($list); ++$i)
			$list[$i] = date($format, $list[$i]);

		ksort($list);
		return array_reverse($list, true);
	}

	function getAll($onlyString = false) {
		$list = array();

		while($entry = $this->dir->read()) {
			if($entry === false)
				break;

			if(substr($entry, 0, 2) != '0x')
				continue;

			$content =join('', file($this->dir->path.$entry)); 
			$list[hexdec(substr($entry, 2))] = $onlyString
				? $content
				: new SimpleRecord_Revision($content, filectime($this->dir->path.$entry));
		}

		$this->dir->rewind();
		ksort($list);
		return array_reverse($list, true);
	}

	function getRecent($onlyString = false) {
		return $this->get(null, $onlyString);
	}

	function get($i = null, $onlyString = false) {
		if(is_null($i))
			$i = $this->getLength() - 1;

		if($i < 0 or $i >= $this->getLength())
			return false;

		if(!isset($this->revisions[$i])) {
			$filename = $this->dir->path.'0x'.dechex($i);
			$this->revisions[$i] = new SimpleRecord_Revision(
				join('', file($filename)),
				filectime($filename)
			);
		}

		if($onlyString)
			return $this->revisions[$i]->getContent();
		else
			return $this->revisions[$i];
	}

	function set($page) {
		if(trim($this->get(null, true)) == trim($page))
			return false;

		$len = $this->getLength();

		if(!$fp = @fopen($this->dir->path.'0x'.dechex($len), 'w'))
			return false;

		if(!fwrite($fp, $page))
			return false;

		fclose($fp);
		@chmod($this->dir->path.'0x'.dechex($len), 0777);

		$this->pages[$len] = $page;
		++$this->count;
		return $len;
	}

	function lock() {
		if(!$fp = @fopen($this->dir->path.'lock', 'w'))
			return false;

		if(!fwrite($fp, $time = time()))
			return false;

		fclose($fp);
		@chmod($this->dir->path.'lock', 0777);
		return $time;
	}

	function unlock() {
		return unlink($this->dir->path.'lock');
	}

	function isLocked($autoUnlock = SimpleRecord_AutoUnlock) {
		if(!is_file($this->dir->path.'lock'))
			return false;

		if(!$fp = @fopen($this->dir->path.'lock'))
			return false;

		$time = (int) fgetc($fp);
		fclose($fp);

		if($autoUnlock and $time + $autoUnlock > time()) {
			$this->unlock();
			return false;
		}
		
		return $time;
	}
}

?>